package com.emm.yixun.website.listeners;

import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.BusinessAbnorma;
import com.emm.yixun.common.model.Customer;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.dto.*;
import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.customer.service.CustomerServiceFacade;
import com.emm.yixun.customer.service.PayDepositServiceFacade;
import com.emm.yixun.customer.service.channel.ChannelSendHttpMessageService;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.RoomChangeHistoryServiceFacade;
import com.emm.yixun.system.service.notice.paydeposit.PayDepositRetreatNoticeFacade;
import com.emm.yixun.website.common.utils.SpringWebContextUtil;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.system.log.ActCommitLogService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

import java.io.Serializable;
import java.util.Date;

public class PayDepositRetreatListeners implements Serializable, ExecutionListener{
	private static final long serialVersionUID = 4854259056621949454L;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id=execution.getProcessBusinessKey();
		String processInstanceId=execution.getProcessInstanceId();
		PayDepositServiceFacade payDepositServiceFacade=getPayDepositServiceFacade();
		BusinessAbnormaServiceFacade businessAbnormaServiceFacade=getBusinessAbnormaServiceFacade();
		Response<BusinessAbnorma> businessAbnormaResponse=businessAbnormaServiceFacade.findById(Long.valueOf(id));
		if(!businessAbnormaResponse.isSuccess()){
			throw new Exception("退认筹记录不存在");
		}
		BusinessAbnorma businessAbnorma=businessAbnormaResponse.getEntity();
		if(null==businessAbnorma){
			throw new Exception("退认筹记录记录不存在");
		}
		Response<PayDeposit> payDepositResponse=payDepositServiceFacade.findById(businessAbnorma.getBusinessId());
		if(!payDepositResponse.isSuccess()){
			throw new Exception("认筹记录不存在");
		}
		PayDeposit payDeposit=payDepositResponse.getEntity();
		if(null==payDeposit){
			throw new Exception("认筹记录不存在");
		}
		if(getActivitiProcessServiceImpl().isCheckPass(processInstanceId)){
			
			boolean flag = checkAuditCommit(payDeposit);
			if(!flag) {
				throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
			}
			
			//认筹记录标示为解除认筹
			PayDepositDto updatePddDto=new PayDepositDto();
			updatePddDto.setId(payDeposit.getId());
			updatePddDto.setBusinessStatus("5");
			Response<Integer> responseUudate=payDepositServiceFacade.updateByPrimaryKey(updatePddDto,true);
			if(!responseUudate.isSuccess()){
				throw new Exception("认筹记录标示为解除认筹出错");
			}
			//更新审核状态
			BusinessAbnormaDto updateDto=new BusinessAbnormaDto();
			updateDto.setId(businessAbnorma.getId());
			updateDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
			updateDto.setCheckDate(new Date());
			Response<Integer> responseBusinessAbnormaDto=businessAbnormaServiceFacade.updateByPrimaryKey(updateDto, true);
			if(!responseBusinessAbnormaDto.isSuccess()){
				throw new Exception("更新退筹审核状态出错");
			}
			//判断是否无房认筹
			if(payDeposit.getIsPaydeposit().equals(IsPaydepositEnum.NO.getNo())){
				//房源状态为未售或者认筹
				//判断是否还有审核中或者审核通过的数据，以此来判断是否返回到可售
				//更改房间状态为未售
				PayDepositDto payDepositDto = new PayDepositDto();
				//审核状态为审核中或已通过且业务状态为认筹或者更名(ym)
				payDepositDto.setM_auditStatus(" and t.audit_status in (1,3) and t.business_status in (1,4)");
				payDepositDto.setRoomId(payDeposit.getRoomId());
				//业务状态为认筹
				ResponseList<PayDeposit> responseList = payDepositServiceFacade.findByDtoJ(payDepositDto);
				if(responseList.getEntity()==null||responseList.getEntity().size()==0){
					ProjectRoomDto projectRoomDto = new ProjectRoomDto();
					projectRoomDto.setId(payDeposit.getRoomId());
					projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());//可售
					Response<Integer> responseRoomDto=getProjectRoomServiceFacade().updateByPrimaryKey(projectRoomDto, true);
					if(!responseRoomDto.isSuccess()){
						throw new Exception("房间状态为可售出错");
					}
				}
				
				//记录房源变更记录
				RoomChangeHistoryDto dto=new RoomChangeHistoryDto();
				dto.setRoomId(payDeposit.getRoomId());
				dto.setBusinessDynamics("退认筹");
				dto.setRemark("房源由【认筹】转为【可售】");
	    		dto.setMerchantId(payDeposit.getMerchantId());
	    		dto.setAccessCode(payDeposit.getAccessCode());
	    		dto.setCreateUserId(payDeposit.getCreateUserId());
	    		dto.setUserCode(payDeposit.getUserCode());
	    		dto.setDelFlag("0");
	    		dto.setUpdateUserId(payDeposit.getUpdateUserId());
	    		dto.setUpdateTime(new Date());
	    		Response<RoomChangeHistoryDto> rchSaveResponse=getRoomChangeHistoryServiceFacade().save(dto);
	    		if(!rchSaveResponse.isSuccess()){
	    			throw new Exception(rchSaveResponse.getResultMessage());
	    		}
			}
			
    		
    		//记录应退款记录
			NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
			needReceiveRefundDto.setRelationId(payDeposit.getId());
			needReceiveRefundDto.setBusinessType("0");
			needReceiveRefundDto.setTotalReceivablesAmount(payDeposit.getPayDepositAmount());
			needReceiveRefundDto.setCustomerId(payDeposit.getCustomerId());
			needReceiveRefundDto.setRoomId(payDeposit.getRoomId());
			needReceiveRefundDto.setStatus("1");
			needReceiveRefundDto.setPostponedStatus("0");
			needReceiveRefundDto.setDocType("1");
			needReceiveRefundDto.setRemark("退筹款");
			needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_2.getNo());
			needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_4.getNo());
			needReceiveRefundDto.setPostponedStatus("0");
			
			needReceiveRefundDto.setMerchantId(payDeposit.getMerchantId());
			needReceiveRefundDto.setUserCode(payDeposit.getUserCode());
			needReceiveRefundDto.setAccessCode(payDeposit.getAccessCode());
			needReceiveRefundDto.setCreateUserId(payDeposit.getCreateUserId());
			needReceiveRefundDto.setDelFlag("0");
			needReceiveRefundDto.setUpdateUserId(payDeposit.getUpdateUserId());
			needReceiveRefundDto.setUpdateTime(new Date());
			Response<NeedReceiveRefundDto> nrrdSaveResponse=getNeedReceiveRefundServiceFacade().save(needReceiveRefundDto);
			if(!nrrdSaveResponse.isSuccess()){
    			throw new Exception(nrrdSaveResponse.getResultMessage());
    		}
			
			/**
			 * 查询客户业务状态，并同步更新客户状态
			 */
			CustomerServiceFacade customerServiceFacade = getCustomerServiceFacade();
			String busStatus = customerServiceFacade.queryCustomerBusiness(payDeposit.getCustomerId());
			CustomerDto cusDto = new CustomerDto();
			cusDto.setId(payDeposit.getCustomerId());
			if(busStatus != null){
				cusDto.setCustomerStatus(CustomerStatusEnum.getByDescription(busStatus).getNo());
				Response<Integer> responseCusDto = customerServiceFacade.updateByPrimaryKey(cusDto, true);
				if(!responseCusDto.isSuccess()){
					throw new Exception("客户状态更新出错");
				}
			}else{
				Response<Customer> customerEntity = customerServiceFacade.findById(payDeposit.getCustomerId());
				if(customerEntity.getEntity().getCustomerStatusBk() == null){
					cusDto.setCustomerStatus(CustomerStatusEnum.VISIT.getNo());
				}else{
					cusDto.setCustomerStatus(customerEntity.getEntity().getCustomerStatusBk());
				}
				Response<Integer> responseCusDto = customerServiceFacade.updateByPrimaryKey(cusDto, true);
				if(!responseCusDto.isSuccess()){
					throw new Exception("客户状态更新出错");
				}
			}

			/**
			 * 推送到渠道
			 */
			getChannelSendHttpMessageService().sendTransaction(payDeposit.getId(), TransTypeEnum.PAYDEPOSIT.getNo(), true);

			/**
			 * （退认筹审核通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(payDeposit.getId());
			noticeEntity.setNoticeType("2");
			noticeEntity.setProcessInstanceId(processInstanceId);
			getPayDepositRetreatNoticeFacade().createPayDepositRetreatNotice(noticeEntity);
		}else{
			
			boolean flag = checkAuditCommit(payDeposit);
			if(!flag) {
				throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
			}
			
			//更新审核状态
			BusinessAbnormaDto updateDto=new BusinessAbnormaDto();
			updateDto.setId(businessAbnorma.getId());
			updateDto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
			updateDto.setCheckDate(new Date());
			Response<Integer> responseBusinessAbnormaDto=businessAbnormaServiceFacade.updateByPrimaryKey(updateDto, true);
			if(!responseBusinessAbnormaDto.isSuccess()){
				throw new Exception("更新退筹审核状态出错");
			}
			
			/**
			 * （退认筹审核不通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(payDeposit.getId());
			noticeEntity.setNoticeType("2");
			noticeEntity.setProcessInstanceId(processInstanceId);
			getPayDepositRetreatNoticeFacade().createPayDepositRetreatNotice(noticeEntity);
		}
	}
	
	/**
	 * 前置判断,审核记录是否已经提交,防止重复提交
	 * 产生原因: 提交审核,后台处理中时,刷新页面再次提交审核,会重复
	 * true: 可继续执行
	 * false: 不可执行
	 */
	public boolean checkAuditCommit(PayDeposit entity) {
		// 业务数据为null时,默认通过.为了不改变老业务,不影响流程正常行走
		if (null == entity) {
			return true;
		}
		return getActcommitLogService().checkActCommit(entity.getAuditStatus(), entity.getMerchantId(), entity.getId(),
				entity.getProcInstId(), "退认筹", "PC");
	}
	
	private ActCommitLogService getActcommitLogService(){
		return (ActCommitLogService)SpringWebContextUtil.getApplicationContext().getBean("actCommitLogService");
	}
	
	private CustomerServiceFacade getCustomerServiceFacade(){
		return (CustomerServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("customerServiceFacade");
	}
	
	private PayDepositRetreatNoticeFacade getPayDepositRetreatNoticeFacade(){
		return (PayDepositRetreatNoticeFacade)SpringWebContextUtil.getApplicationContext().getBean("payDepositRetreatNoticeFacade");
	}
	
	private BusinessAbnormaServiceFacade getBusinessAbnormaServiceFacade(){
		return (BusinessAbnormaServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("businessAbnormaServiceFacade");
	}
	
	private NeedReceiveRefundServiceFacade getNeedReceiveRefundServiceFacade(){
		return (NeedReceiveRefundServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("needReceiveRefundServiceFacade");
	}
	
	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl(){
		return (ActivitiProcessServiceImpl)SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}
	
	private PayDepositServiceFacade getPayDepositServiceFacade(){
		return (PayDepositServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("payDepositServiceFacade");
	}
	
	private ProjectRoomServiceFacade getProjectRoomServiceFacade(){
		return (ProjectRoomServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectRoomServiceFacade");
	}
	
	private RoomChangeHistoryServiceFacade getRoomChangeHistoryServiceFacade(){
		return (RoomChangeHistoryServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("roomChangeHistoryServiceFacade");
	}

	private ChannelSendHttpMessageService getChannelSendHttpMessageService(){
		return (ChannelSendHttpMessageService)SpringWebContextUtil.getApplicationContext().getBean("channelSendHttpMessageService");
	}

}
